package com.gopay.checkorder.service.task;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;


import com.gopay.common.cipher.utils.LoggerMaskUtils;
import com.gopay.gass.service.GassPayRemoteService;

import org.apache.commons.lang3.time.StopWatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.checkorder.dao.BankOrderDAO;
import com.gopay.checkorder.dao.BcdlQueryBalanceDAO;
import com.gopay.checkorder.dao.BisBankOrderQueryDAO;
import com.gopay.checkorder.manager.BankOrderManager;
import com.gopay.checkorder.service.BankOrderService;
import com.gopay.checkorder.service.BcdlOrderSendBankService;
import com.gopay.checkorder.service.sentinel.BcdlOrderSentinel;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BankOrderStatus;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.cps.manager.order.CpsGeneralMainOrderQueryManager;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.BcdlQueryBalance;
import com.gopay.common.domain.bank.BcdlResult;
import com.gopay.common.domain.cps.vo.CheckOrderResult;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.HttpTransport;
import com.gopay.common.util.spring.SpringContextUtil;

public class BcdlOrderCheckEmitterTaskImpl implements Task {
	private final static Logger logger = LoggerFactory.getLogger(BcdlOrderCheckEmitterTaskImpl.class);

    //modified by zyt，单独摘出一个service，针对银企直联处理
	/*@Resource(name = "bankOrderService")
	private BankOrderService bankOrderService;*/
    @Resource(name = "bcdlBankOrderService")
    private BankOrderService bcdlBankOrderService;

	private int MAX_SIZE=100;
	
    @Resource(name = "cpsGeneralMainOrderQueryManager")
    protected CpsGeneralMainOrderQueryManager mainOrderQuery;
    @Resource(name = "bankOrderManager")
    protected BankOrderManager bankOrderManager;
    @Resource(name = "bisBankOrderQueryDAO")
    private BisBankOrderQueryDAO bisBankOrderQueryDAO;
    @Resource(name = "bcdlQueryBalanceDAO")
    private BcdlQueryBalanceDAO bcdlQueryBalanceDAO;
    @Resource(name = "bankOrderDAO")
    private BankOrderDAO bankOrderDAO;
    @Resource(name = "gassPayService")
    private GassPayRemoteService gassPayService;
	private String bank;
	private String notifyCpsUrl;
	private BcdlOrderSentinel sentinel;
	
	@Override
	public void doTask() {
	    logger.info("银企直连对账job--开始，bank="+bank);
        process(bank);
        logger.info("银企直连对账job--结束，bank="+bank);
	}

	public void process(String bank) {
		try {
			StopWatch sw = new StopWatch();
		    sw.start();
		    	  
            String beanName = getSendBankBeanName(bank);

            if (false == SpringContextUtil.containsBean(beanName)) {
                logger.info("spring bean does not exist: " + beanName);
                return;
            }

            BcdlOrderSendBankService sendBankService = (BcdlOrderSendBankService) SpringContextUtil.getBean(beanName);
		    
			List<BankOrder> checkOrders = getCheckOrder(bank);
			sw.split();
            logger.error(bank+"-----------getCheckOrder耗时="+sw.getSplitTime());
            
            sw.stop();
			
			logger.error("-----------"+bank+"对单记录总数="+checkOrders.size());
			
			HttpTransport notifyGass = new HttpTransport();
            notifyGass.setSendEncoding("UTF-8");
			
			for (BankOrder bankOrder : checkOrders) {
				CheckOrderResult result = null;
			    try{
				
    				logger.error("银企直连 对单--开始 ，orderId="+bankOrder.getOrderId()+",bank="+bank);
    				result =checkOrder(bankOrder, BankOrderStatus.AUTO_CHECK_SUCCESS);
    				logger.error("银企直连 对单--结束 ，orderId="+bankOrder.getOrderId()+",ErrCode="+result.getErrCode()+",isSuccess="+result.isSuccess());
                    
    				
    				Map<String, String> param = new HashMap<String, String>();
    				if (ProcCodeConstants.PROC_CODE_100E6027.equals(result.getErrCode())) {
    					param.put("resultCode", "2");
                        //delete by zyt,2017-8-4，删除remark标志
                        // param.put("remark", "2");
    					if(result.isNeedRefund()){
    						param.put("needRefund", "1");
    					}
    					param.put("resultMsg", result.getErrMsg());
    					param.put("gopayOrderId", bankOrder.getOrderId());
    					/*notifyGass.setUrl(bankOrder.getRemark2());
    					notifyGass.submit(param);*/ //生产优化10期 lx httpclient 替换为 hessian
                        gassPayService.bcdlNotifyGass(param);
    				}else if(result.isSuccess()){
    					param.put("resultCode", "1");
                        //delete by zyt,2017-8-4，删除remark标志
                        // param.put("remark", "2");
    					param.put("gopayOrderId", bankOrder.getOrderId());
    					/*notifyGass.setUrl(bankOrder.getRemark2());
    					notifyGass.submit(param);*///生产优化10期 lx httpclient 替换为 hessian
                        gassPayService.bcdlNotifyGass(param);
    				}else{
    					param.put("resultCode", "3");
                        //delete by zyt,2017-8-4，删除remark标志
                        // param.put("remark", "2");
    					param.put("gopayOrderId", bankOrder.getOrderId());
    					/*notifyGass.setUrl(bankOrder.getRemark2());
    					notifyGass.submit(param);*///生产优化10期 lx httpclient 替换为 hessian
                        gassPayService.bcdlNotifyGass(param);
    				}
    				
				
			    } catch (Exception e) {
                    logger.error("对单异常 ，orderId="+bankOrder.getOrderId()+",bank="+bank,e);
                }
			    finally {
                    sentinel.checkPartol(bankOrder, result);
                }
				
			}
			
			// 查询账户余额
            List<BcdlQueryBalance> bcdlQuerys = getBcdlQueryOrder(bank);
            if (bcdlQuerys == null || bcdlQuerys.size() <= 0) {
                logger.error("bcdl queryBalance orders is null");
                return;
            }
            BcdlQueryBalance bcdlQuery = bcdlQuerys.get(0);
            logger.error("银企直连 查询余额--开始 ，orderId=" + bcdlQuery.getQueryOrderId() + ",bank=" + bank);
            BcdlResult result =sendBankService.queryBalance(bcdlQuery);
            logger.error("银企直连 查询余额--结束 ，orderId=" + bcdlQuery.getQueryOrderId() + ",ResultCode=" + result.getResultCode()
                    + ",isSuccess=" + result.isSuccess());
            
            notifyCps(bank, result);
		} catch (Exception e) {
			logger.error("checkOrder error message: ,bank="+bank, e);
		}
	}

	// edited by lilili 工行跨行大额增加对账次数
	public List<BankOrder> getCheckOrder(String bank) {
		List<BankOrder> bankOrders = null;
		if (bank.equals(BankConstants.BANK_LOGO_ICBC)) {
			bankOrders = bisBankOrderQueryDAO.getCheckBcdlOrderByBanklarge(bank, BankOrderStatus.PROCESS, 1, MAX_SIZE);
		}else{
			bankOrders = bisBankOrderQueryDAO.getCheckBcdlOrderByBank(bank, BankOrderStatus.PROCESS, 1, MAX_SIZE);
		}
		return bankOrders;
	}

	public List<BcdlQueryBalance> getBcdlQueryOrder(String bank) {
        return bcdlQueryBalanceDAO.getBcdlQueryByBankCodeAndOrderStatus(bank, BankOrderStatus.ACCEPTED);
    }

	public CheckOrderResult checkOrder(BankOrder bankOrder, String target) {
		CheckOrderResult checkOrderResult = new CheckOrderResult();
		checkOrderResult = bcdlBankOrderService.checkOrder(bankOrder, target);
		return checkOrderResult;
	}
	
	private String getSendBankBeanName(String bankCode) throws GopayException {
        String beanName = bankCode + "-BCDL";
        return beanName;
    }
	
    private String notifyCps(String bank, BcdlResult result) {
        String notifyUrl = null;
        if (ProcCodeConstants.PROC_CODE_100S1000.equals(result.getResultCode())) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");

            StringBuffer paramters = new StringBuffer();
            StringBuffer paramtersLog = new StringBuffer();
            paramters.append(notifyCpsUrl).append("?");
            paramters.append("resultCode=").append(ProcCodeConstants.PROC_CODE_100S1000);
            paramters.append("&bankCode=").append(bank);
            paramters.append("&bankAcctAmt=").append((String) result.getModel("balance"));
            paramters.append("&bankName=").append(getBankName(bank));
            paramtersLog.append(paramters);
            paramters.append("&bankCardNo=").append((String) result.getModel("payAccNum"));
            paramters.append("&bankAcctLastUpdTs=").append(sdf.format(new Date()));
            paramtersLog.append("&bankCardNo=").append(LoggerMaskUtils.maskString((String) result.getModel("payAccNum")));
            paramtersLog.append("&bankAcctLastUpdTs=").append(sdf.format(new Date()));
            notifyUrl = paramters.toString();
            logger.error("银企直连 查询余额--通知cps开始 ，响应信息：" + paramtersLog);
        } else {
            StringBuffer paramters = new StringBuffer();
            paramters.append(notifyCpsUrl).append("?");
            paramters.append("resultCode=").append(ProcCodeConstants.PROC_CODE_100E6027);
            paramters.append("&bankCode=").append(bank);
            notifyUrl = paramters.toString();
            logger.error("银企直连 查询余额--通知cps开始 ，响应信息：" + notifyUrl);
        }

        StringBuffer sb = new StringBuffer();
        try {
            URL hp = new URL(notifyUrl);
            URLConnection conn = hp.openConnection();
            conn.connect();
            InputStream is = conn.getInputStream();
            java.io.BufferedReader in = new BufferedReader(new InputStreamReader(is, "utf-8"));

            String line = "";
            while ((line = in.readLine()) != null) {
                sb.append(line);
            }
            in.close();
            logger.error("银企直连 查询余额--通知cps结束 ： " + sb.toString());
        } catch (Exception e) {
            logger.error("银企直连 查询余额--通知cps报错: ", e);
            return null;
        }

        return sb.toString();
    }
	
    private String getBankName(String bank) {
        if (bank.equals(BankConstants.BANK_LOGO_ICBC)) {
            return "工商银行";
        } else if (bank.equals(BankConstants.BANK_LOGO_ABC)) {
            return "农业银行";
        } else if (bank.equals(BankConstants.BANK_LOGO_CMB)) {
            return "招商银行";
        } else {
            return null;
        }
    }

	/*public BankOrderService getBankOrderService() {
		return bankOrderService;
	}

	public void setBankOrderService(BankOrderService bankOrderService) {
		this.bankOrderService = bankOrderService;
	}
    */

    public BankOrderService getBcdlBankOrderService() {
        return bcdlBankOrderService;
    }

    public void setBcdlBankOrderService(BankOrderService bcdlBankOrderService) {
        this.bcdlBankOrderService = bcdlBankOrderService;
    }

    public void setBank(String bank) {
        this.bank = bank;
    }

	public void setNotifyCpsUrl(String notifyCpsUrl) {
        this.notifyCpsUrl = notifyCpsUrl;
    }

    public CpsGeneralMainOrderQueryManager getMainOrderQuery() {
		return mainOrderQuery;
	}

	public void setMainOrderQuery(CpsGeneralMainOrderQueryManager mainOrderQuery) {
		this.mainOrderQuery = mainOrderQuery;
	}

	public BankOrderManager getBankOrderManager() {
		return bankOrderManager;
	}

	public void setBankOrderManager(BankOrderManager bankOrderManager) {
		this.bankOrderManager = bankOrderManager;
	}

	public void setSentinel(BcdlOrderSentinel sentinel) {
		this.sentinel = sentinel;
	}

}
